﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using KM.Framework.Utility;
using Microsoft.Practices.Prism.Commands;

namespace KM.Framework.Business
{
    public class ViewModelBase : BindingObj
    {
        private Visibility _ViewVisibility = Visibility.Visible;
        /// <summary>
        /// 是否显示视图
        /// </summary>
        public Visibility ViewVisibility
        {
            get { return _ViewVisibility; }
            set
            {
                _ViewVisibility = value;
                RaisePropertyChanged("ViewVisibility");
            }
        }

        private bool? _CloseResult;
        /// <summary>
        /// 此属性在弹出window时有效，用来关闭窗口，并设定DialogResult的值,CloseResult一但设值
        /// 窗口将自动关闭，DialogResult=CloseResult
        /// </summary>
        public bool? CloseResult
        {
            get
            {
                return _CloseResult;
            }
            set
            {
                _CloseResult = value;
                this.RaisePropertyChanged(p => p.CloseResult);
            }
        }

        #region 菜单集合 Commands
        private ObservableCollection<CommandItem> _Commands;
        public ObservableCollection<CommandItem> Commands
        {
            get { return _Commands ?? (_Commands = new ObservableCollection<CommandItem>()); }
            set
            {
                _Commands = value;
                this.RaisePropertyChanged("Commands");
            }
        }

        #endregion

        private HashSet<ViewModelBase> FriendList = new HashSet<ViewModelBase>();//朋友集合

        private HashSet<DelegateCommandBase> _CommandList = new HashSet<DelegateCommandBase>();
        public HashSet<DelegateCommandBase> CommandList
        {
            get { return _CommandList; }
        }

        public DelegateCommand<T> CreateCheckCommand<T>(Action<T> executeMethod, Func<T, bool> canExecuteMethod)
        {
            Action<T> executeCommandMethod = new Action<T>((obj) =>
            {
                if (executeMethod != null)
                    executeMethod(obj);
                this.RaiseCanExecuteChanged();
            });
            DelegateCommand<T> cmd = new DelegateCommand<T>(executeCommandMethod, canExecuteMethod);
            this.CommandList.Add(cmd);
            return cmd;
        }

        public DelegateCommand CreateCheckCommand(Action executeMethod, Func<bool> canExecuteMethod)
        {
            Action executeCommandMethod = new Action(() =>
            {
                if (executeMethod != null)
                    executeMethod();
                this.RaiseCanExecuteChanged();
            });
            DelegateCommand cmd = new DelegateCommand(executeCommandMethod, canExecuteMethod);
            this.CommandList.Add(cmd);
            return cmd;
        }

        /// <summary>
        /// 创建不需要检查的Command
        /// </summary>
        public DelegateCommand<T> CreateCommand<T>(Action<T> executeMethod)
        {
            return new DelegateCommand<T>(executeMethod);
        }

        /// <summary>
        /// 创建不需要检查的Command
        /// </summary>
        public DelegateCommand CreateCommand(Action executeMethod)
        {
            return new DelegateCommand(executeMethod);
        }
 

        private void RaiseCanExecuteChanged(ViewModelBase vm)
        {
            foreach (var cmd in vm.CommandList)
            {
                cmd.RaiseCanExecuteChanged();
            }
        }

        public void RaiseCanExecuteChanged()
        {
            RaiseCanExecuteChanged(this);
            foreach (ViewModelBase friend in this.FriendList)
            {
                RaiseCanExecuteChanged(friend);
            }
        }

        private void AddFriend(ViewModelBase newFriend)
        {
            foreach (ViewModelBase friend in this.FriendList)
            {
                if (friend == newFriend)
                    return;
            }

            this.FriendList.Add(newFriend);
        }

        /// <summary>
        /// 握手(互相结盟)
        /// </summary>
        public static void ShakeHands(params ViewModelBase[] friends)
        {
            for (int i = 0; i < friends.Length - 1; i++)
            {
                ViewModelBase friend1 = friends[i];
                for (int j = i + 1; j < friends.Length; j++)
                {
                    ViewModelBase friend2 = friends[j];

                    friend1.AddFriend(friend2);
                    friend2.AddFriend(friend1);
                }
            }
        }
    }
}
